package com.feihe.service;

import com.feihe.dto.*;
import com.feihe.entity.Calendar;
import com.feihe.entity.Reservation;
import com.feihe.entity.User;
import com.feihe.repository.CalendarRepository;
import com.feihe.repository.ReservationRepository;
import com.feihe.repository.UserRepository;
import com.feihe.util.IpUtil;
import com.feihe.util.QRCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class ReservationService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private ReservationRepository reservationRepository;
    
    @Autowired
    private CalendarRepository calendarRepository;
    
    @Value("${app.base-url}")
    private String baseUrl;
    
    @Value("${app.qrcode.path}")
    private String qrcodePath;
    
    @Value("${app.qrcode.matrix-point-size}")
    private int matrixPointSize;
    
    private static final int MAX_VISITORS = 50;
    
    /**
     * 获取未来7天信息
     */
    public List<DayInfo> getDays() {
        List<DayInfo> days = new ArrayList<>();
        LocalDate today = LocalDate.now();
        
        for (int i = 0; i < 7; i++) {
            LocalDate date = today.plusDays(i);
            String dayStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String weekStr = getWeekString(date.getDayOfWeek().getValue());
            Integer isOpen = date.isEqual(today) || date.isAfter(today) ? 1 : 0;
            
            days.add(new DayInfo(dayStr, weekStr, isOpen));
        }
        
        return days;
    }
    
    /**
     * 获取场地信息
     */
    public List<GroundInfo> getGrounds() {
        List<GroundInfo> grounds = new ArrayList<>();
        String imageUrl = baseUrl + "images/das.png";
        String detail = "奇趣探秘、知识科普、多样互动，了解WCM世界级工厂管理体系见证一滴牛奶华丽变身为奶粉的过程，探索探索中国飞鹤对高品质奶粉不懈追求背后的故事。";
        
        for (int i = 1; i <= 4; i++) {
            grounds.add(new GroundInfo(i, imageUrl, "飞鹤（哈尔滨）智能工厂" + i, detail + i));
        }
        
        return grounds;
    }
    
    /**
     * 获取时间段信息
     */
    public List<TimeSlot> getTimeSlots(String day, Integer ground) {
        List<TimeSlot> timeSlots = new ArrayList<>();
        String[] times = {
            "09:00-10:00", "10:00-11:00", "11:00-12:00", "12:00-13:00",
            "13:00-14:00", "14:00-15:00", "15:00-16:00", "16:00-17:00"
        };
        
        for (String time : times) {
            TimeSlot slot = new TimeSlot(time);
            String[] timeParts = time.split("-");
            
            LocalDateTime startTime = LocalDateTime.parse(day + " " + timeParts[0] + ":00", 
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDateTime endTime = LocalDateTime.parse(day + " " + timeParts[1] + ":00", 
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            
            // 检查日历维护状态
            Optional<Calendar> calendar = calendarRepository.findByTimeRange(startTime, endTime);
            if (calendar.isPresent()) {
                slot.setStatus(calendar.get().getStatusText());
            } else {
                // 检查预约状态
                List<Reservation> reservations = reservationRepository.findByGroundAndTimeRange(ground, startTime, endTime);
                if (!reservations.isEmpty()) {
                    slot.setStatus("已预约");
                } else {
                    // 检查人数限制
                    Integer visitorCount = reservationRepository.sumVisitorNumbersByGroundAndTimeRange(ground, startTime, endTime);
                    if (visitorCount == null) {
                        visitorCount = 0;
                    }
                    
                    if (visitorCount < MAX_VISITORS) {
                        slot.setIsOpen(1);
                    } else {
                        slot.setStatus("人数已满");
                    }
                }
            }
            
            timeSlots.add(slot);
        }
        
        return timeSlots;
    }
    
    /**
     * 创建预约
     */
    public Map<String, Object> createReservation(ReservationRequest request, HttpServletRequest httpRequest) {
        // 获取或创建用户
        User user = userRepository.findByMemberId(request.getMemberId()).orElse(null);
        if (user == null) {
            String ip = IpUtil.getRealIp(httpRequest);
            user = new User(request.getMemberId(), ip, LocalDateTime.now());
            user = userRepository.save(user);
        }
        
        // 解析时间
        String[] timeParts = request.getReservationTime().split("-");
        LocalDateTime startTime = LocalDateTime.parse(request.getReservationDate() + " " + timeParts[0] + ":00", 
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endTime = LocalDateTime.parse(request.getReservationDate() + " " + timeParts[1] + ":00", 
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        
        // 检查日历维护状态
        Optional<Calendar> calendar = calendarRepository.findByTimeRange(startTime, endTime);
        if (calendar.isPresent()) {
            throw new RuntimeException("该时间段不可预约");
        }
        
        // 检查是否已预约
        List<Reservation> existingReservations = reservationRepository.findByGroundAndTimeRange(
            request.getGround(), startTime, endTime);
        if (!existingReservations.isEmpty()) {
            throw new RuntimeException("已预约");
        }
        
        // 检查人数限制
        Integer currentVisitors = reservationRepository.sumVisitorNumbersByGroundAndTimeRange(
            request.getGround(), startTime, endTime);
        if (currentVisitors == null) {
            currentVisitors = 0;
        }
        
        if (currentVisitors + request.getVisitorNumber() > MAX_VISITORS) {
            throw new RuntimeException("预约人数已满");
        }
        
        // 创建预约
        Reservation reservation = new Reservation();
        reservation.setUserId(user.getId());
        reservation.setUniqid(generateUniqid());
        reservation.setGround(request.getGround());
        reservation.setRealname(request.getRealname());
        reservation.setTelephone(request.getTelephone());
        reservation.setVisitorNumber(request.getVisitorNumber());
        reservation.setType(request.getType());
        reservation.setReservationStartTime(startTime);
        reservation.setReservationEndTime(endTime);
        reservation.setCreateTime(LocalDateTime.now());
        
        reservation = reservationRepository.save(reservation);
        
        Map<String, Object> result = new HashMap<>();
        result.put("id", reservation.getId());
        return result;
    }
    
    /**
     * 取消预约
     */
    public void cancelReservation(Long id) {
        Optional<Reservation> reservation = reservationRepository.findById(id);
        if (reservation.isPresent()) {
            reservationRepository.deleteById(id);
        }
    }
    
    /**
     * 签到
     */
    public void checkIn(String uniqid) {
        Optional<Reservation> reservation = reservationRepository.findByUniqid(uniqid);
        if (reservation.isPresent()) {
            Reservation r = reservation.get();
            r.setIsCheck(1);
            reservationRepository.save(r);
        }
    }
    
    /**
     * 获取预约详情
     */
    public Map<String, Object> getReservationDetail(Long id) {
        Optional<Reservation> optionalReservation = reservationRepository.findById(id);
        if (!optionalReservation.isPresent()) {
            throw new RuntimeException("预约不存在");
        }
        
        Reservation reservation = optionalReservation.get();
        
        Map<String, Object> result = new HashMap<>();
        result.put("id", reservation.getId());
        result.put("uniqid", reservation.getUniqid());
        result.put("ground", reservation.getGround());
        result.put("realname", reservation.getRealname());
        result.put("telephone", reservation.getTelephone());
        result.put("visitor_number", reservation.getVisitorNumber());
        result.put("type", reservation.getType());
        result.put("is_check", reservation.getIsCheck());
        
        // 格式化时间
        result.put("week", reservation.getReservationStartTime().getDayOfWeek().getValue());
        result.put("reservation_date", reservation.getReservationStartTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        result.put("reservation_start_time", reservation.getReservationStartTime().format(DateTimeFormatter.ofPattern("HH:mm")));
        result.put("reservation_end_time", reservation.getReservationEndTime().format(DateTimeFormatter.ofPattern("HH:mm")));
        
        // 设置标题
        result.put("title", "飞鹤营养科技体验中心" + reservation.getGround());
        
        // 生成二维码
        try {
            String filename = qrcodePath + reservation.getId() + ".png";
            QRCodeUtil.generateQRCode(reservation.getUniqid(), filename, matrixPointSize * 10);
            result.put("qrcode", baseUrl + filename);
        } catch (Exception e) {
            throw new RuntimeException("二维码生成失败", e);
        }
        
        return result;
    }
    
    /**
     * 获取用户预约列表
     */
    public List<Map<String, Object>> getReservationList(String memberId, Integer type) {
        Optional<User> user = userRepository.findByMemberId(memberId);
        if (!user.isPresent()) {
            return new ArrayList<>();
        }
        
        Integer isCheck = type == 1 ? 0 : 1; // 1:未签到, 2:已签到
        List<Reservation> reservations = reservationRepository.findByUserIdAndIsCheck(user.get().getId(), isCheck);
        
        List<Map<String, Object>> result = new ArrayList<>();
        for (Reservation reservation : reservations) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", reservation.getId());
            
            String startTime = reservation.getReservationStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            String endTime = reservation.getReservationEndTime().format(DateTimeFormatter.ofPattern("HH:mm"));
            item.put("date", startTime + "-" + endTime);
            
            item.put("title", "飞鹤营养科技体验中心" + reservation.getGround());
            
            result.add(item);
        }
        
        return result;
    }
    
    private String getWeekString(int dayOfWeek) {
        switch (dayOfWeek) {
            case 1: return "周一";
            case 2: return "周二";
            case 3: return "周三";
            case 4: return "周四";
            case 5: return "周五";
            case 6: return "周六";
            case 7: return "周日";
            default: return "";
        }
    }
    
    private String generateUniqid() {
        return System.currentTimeMillis() + "" + (int)(Math.random() * 1000);
    }
} 